home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / RANDOM.C < prev    next >
C/C++ Source or Header  |  1991-03-10  |  11KB  |  440 lines

  1. /*
  2.  *        Assorted commands.
  3.  * The file contains the command
  4.  * processors for a large assortment of unrelated
  5.  * commands. The only thing they have in common is
  6.  * that they are all command processors.
  7.  */
  8. #include    "def.h"
  9.  
  10. /*
  11.  * Display a bunch of useful information about
  12.  * the current location of dot. The character under the
  13.  * cursor (in octal), the current line, row, and column, and
  14.  * approximate position of the cursor in the file (as a percentage)
  15.  * is displayed. The column position assumes an infinite position
  16.  * display; it does not truncate just because the screen does.
  17.  * This is normally bound to "C-X =".
  18.  */
  19. /*ARGSUSED*/
  20. showcpos(f, n)
  21. {
  22.     register LINE    *clp;
  23.     register long    nchar;
  24.     long        cchar;
  25.     register int    nline, row;
  26.     int        cline, cbyte;    /* Current line/char/byte */
  27.     int        ratio;
  28.  
  29.     clp = lforw(curbp->b_linep);        /* Collect the data.    */
  30.     nchar = 0;
  31.     nline = 0;
  32.     for (;;) {
  33.         ++nline;            /* Count this line    */
  34.         if (clp == curwp->w_dotp) {
  35.             cline = nline;        /* Mark line        */
  36.             cchar = nchar + curwp->w_doto;
  37.             if (curwp->w_doto == llength(clp))
  38.                 cbyte = '\n';
  39.             else
  40.                 cbyte = lgetc(clp, curwp->w_doto);
  41.         }
  42.         nchar += llength(clp);        /* Now count the chars    */
  43.         clp = lforw(clp);
  44.         if (clp == curbp->b_linep) break;
  45.         nchar++;            /* count the newline    */
  46.     }
  47.     row = curwp->w_toprow + 1;        /* Determine row.    */
  48.     clp = curwp->w_linep;
  49.     while (clp!=curbp->b_linep && clp!=curwp->w_dotp) {
  50.         ++row;
  51.         clp = lforw(clp);
  52.     }
  53.     /*NOSTRICT*/
  54.     ratio = nchar ? (100L*cchar) / nchar : 100;
  55.     ewprintf("Char: %c (0%o)  point=%ld(%d%%)  line=%d  row=%d  col=%d",
  56.         cbyte, cbyte, cchar, ratio, cline, row, getcolpos());
  57.     return TRUE;
  58. }
  59.  
  60. getcolpos() {
  61.     register int    col, i, c;
  62.  
  63.     col = 1;                /* Determine column.    */
  64.     for (i=0; i<curwp->w_doto; ++i) {
  65.         c = lgetc(curwp->w_dotp, i);
  66.         if (c == '\t'
  67. #ifdef    NOTAB
  68.             && !(curbp->b_flag & BFNOTAB)
  69. #endif
  70.             ) {
  71.             col |= 0x07;
  72.             ++col;
  73.         } else if (ISCTRL(c) != FALSE)
  74.             ++col;
  75.         ++col;
  76.     }
  77.     return col;
  78. }
  79. /*
  80.  * Twiddle the two characters on either side of
  81.  * dot. If dot is at the end of the line twiddle the
  82.  * two characters before it. Return with an error if dot
  83.  * is at the beginning of line; it seems to be a bit
  84.  * pointless to make this work. This fixes up a very
  85.  * common typo with a single stroke. Normally bound
  86.  * to "C-T". This always works within a line, so
  87.  * "WFEDIT" is good enough.
  88.  */
  89. /*ARGSUSED*/
  90. twiddle(f, n)
  91. {
  92.     register LINE    *dotp;
  93.     register int    doto;
  94.     register int    cr;
  95.     VOID     lchange();
  96.  
  97.     dotp = curwp->w_dotp;
  98.     doto = curwp->w_doto;
  99.     if(doto==llength(dotp)) {
  100.         if(--doto<=0) return FALSE;
  101.     } else {
  102.         if(doto==0) return FALSE;
  103.         ++curwp->w_doto;
  104.     }
  105.     cr = lgetc(dotp, doto--);
  106.     lputc(dotp, doto+1, lgetc(dotp, doto));
  107.     lputc(dotp, doto, cr);
  108.     lchange(WFEDIT);
  109.     return TRUE;
  110. }
  111.  
  112. /*
  113.  * Open up some blank space. The basic plan
  114.  * is to insert a bunch of newlines, and then back
  115.  * up over them. Everything is done by the subcommand
  116.  * procerssors. They even handle the looping. Normally
  117.  * this is bound to "C-O".
  118.  */
  119. /*ARGSUSED*/
  120. openline(f, n)
  121. {
  122.     register int    i;
  123.     register int    s;
  124.  
  125.     if (n < 0)
  126.         return FALSE;
  127.     if (n == 0)
  128.         return TRUE;
  129.     i = n;                    /* Insert newlines.    */
  130.     do {
  131.         s = lnewline();
  132.     } while (s==TRUE && --i);
  133.     if (s == TRUE)                /* Then back up overtop */
  134.         s = backchar(f | FFRAND, n);    /* of them all.        */
  135.     return s;
  136. }
  137.  
  138. /*
  139.  * Insert a newline.
  140.  * If you are at the end of the line and the
  141.  * next line is a blank line, just move into the
  142.  * blank line. This makes "C-O" and "C-X C-O" work
  143.  * nicely, and reduces the ammount of screen
  144.  * update that has to be done. This would not be
  145.  * as critical if screen update were a lot
  146.  * more efficient.
  147.  */
  148. /*ARGSUSED*/
  149. newline(f, n)
  150. {
  151.     register LINE    *lp;
  152.     register int    s;
  153.  
  154.     if (n < 0) return FALSE;
  155.     while (n--) {
  156.         lp = curwp->w_dotp;
  157.         if (llength(lp) == curwp->w_doto
  158.         && lforw(lp) != curbp->b_linep
  159.         && llength(lforw(lp)) == 0) {
  160.             if ((s=forwchar(FFRAND, 1)) != TRUE)
  161.                 return s;
  162.         } else if ((s=lnewline()) != TRUE)
  163.             return s;
  164.     }
  165.     return TRUE;
  166. }
  167.  
  168. /*
  169.  * Delete blank lines around dot.
  170.  * What this command does depends if dot is
  171.  * sitting on a blank line. If dot is sitting on a
  172.  * blank line, this command deletes all the blank lines
  173.  * above and below the current line. If it is sitting
  174.  * on a non blank line then it deletes all of the
  175.  * blank lines after the line. Normally this command
  176.  * is bound to "C-X C-O". Any argument is ignored.
  177.  */
  178. /*ARGSUSED*/
  179. deblank(f, n)
  180. {
  181.     register LINE    *lp1;
  182.     register LINE    *lp2;
  183.     register RSIZE    nld;
  184.  
  185.     lp1 = curwp->w_dotp;
  186.     while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
  187.         lp1 = lp2;
  188.     lp2 = lp1;
  189.     nld = (RSIZE) 0;
  190.     while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
  191.         ++nld;
  192.     if (nld == 0)
  193.         return (TRUE);
  194.     curwp->w_dotp = lforw(lp1);
  195.     curwp->w_doto = 0;
  196.     return ldelete((RSIZE)nld, KNONE);
  197. }
  198.  
  199. /*
  200.  * Delete any whitespace around dot, then insert a space.
  201.  */
  202. justone(f, n) {
  203.     (VOID) delwhite(f, n);
  204.     return linsert(1, ' ');
  205. }
  206. /*
  207.  * Delete any whitespace around dot.
  208.  */
  209. /*ARGSUSED*/
  210. delwhite(f, n)
  211. {
  212.     register int    col, c, s;
  213.  
  214.     col = curwp->w_doto;
  215.     while (((c = lgetc(curwp->w_dotp, col)) == ' ' || c == '\t')
  216.             && col < llength(curwp->w_dotp))
  217.         ++col;
  218.     do {
  219.         if (curwp->w_doto == 0) {
  220.             s = FALSE;
  221.             break;
  222.         }
  223.         if ((s = backchar(FFRAND, 1)) != TRUE) break;
  224.     } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ' || c == '\t');
  225.  
  226.     if (s == TRUE) (VOID) forwchar(FFRAND, 1);
  227.     (VOID) ldelete((RSIZE)(col - curwp->w_doto), KNONE);
  228.     return TRUE;
  229. }
  230. /*
  231.  * Insert a newline, then enough
  232.  * tabs and spaces to duplicate the indentation
  233.  * of the previous line. Assumes tabs are every eight
  234.  * characters. Quite simple. Figure out the indentation
  235.  * of the current line. Insert a newline by calling
  236.  * the standard routine. Insert the indentation by
  237.  * inserting the right number of tabs and spaces.
  238.  * Return TRUE if all ok. Return FALSE if one
  239.  * of the subcomands failed. Normally bound
  240.  * to "C-J".
  241.  */
  242. /*ARGSUSED*/
  243. indent(f, n)
  244. {
  245.     register int    nicol;
  246.     register int    c;
  247.     register int    i;
  248.  
  249.     if (n < 0) return (FALSE);
  250.     while (n--) {
  251.         nicol = 0;
  252.         for (i=0; i<llength(curwp->w_dotp); ++i) {
  253.             c = lgetc(curwp->w_dotp, i);
  254.             if (c!=' ' && c!='\t')
  255.                 break;
  256.             if (c == '\t')
  257.                 nicol |= 0x07;
  258.             ++nicol;
  259.         }
  260.         if (lnewline() == FALSE || ((
  261. #ifdef    NOTAB
  262.             curbp->b_flag&BFNOTAB) ?
  263.             linsert(nicol, ' ') == FALSE : (
  264. #endif
  265.             ((i=nicol/8)!=0 && linsert(i, '\t')==FALSE) ||
  266.             ((i=nicol%8)!=0 && linsert(i,  ' ')==FALSE))))
  267.             return FALSE;
  268.     }
  269.     return TRUE;
  270. }
  271.  
  272. /*
  273.  * Delete forward. This is real
  274.  * easy, because the basic delete routine does
  275.  * all of the work. Watches for negative arguments,
  276.  * and does the right thing. If any argument is
  277.  * present, it kills rather than deletes, to prevent
  278.  * loss of text if typed with a big argument.
  279.  * Normally bound to "C-D".
  280.  */
  281. /*ARGSUSED*/
  282. forwdel(f, n)
  283. {
  284.     if (n < 0)
  285.         return backdel(f | FFRAND, -n);
  286.     if (f & FFARG) {            /* Really a kill.    */
  287.         if ((lastflag&CFKILL) == 0)
  288.             kdelete();
  289.         thisflag |= CFKILL;
  290.     }
  291.     return ldelete((RSIZE) n, (f & FFARG) ? KFORW : KNONE);
  292. }
  293.  
  294. /*
  295.  * Delete backwards. This is quite easy too,
  296.  * because it's all done with other functions. Just
  297.  * move the cursor back, and delete forwards.
  298.  * Like delete forward, this actually does a kill
  299.  * if presented with an argument.
  300.  */
  301. /*ARGSUSED*/
  302. backdel(f, n)
  303. {
  304.     register int    s;
  305.  
  306.     if (n < 0)
  307.         return forwdel(f | FFRAND, -n);
  308.     if (f & FFARG) {            /* Really a kill.    */
  309.         if ((lastflag&CFKILL) == 0)
  310.             kdelete();
  311.         thisflag |= CFKILL;
  312.     }
  313.     if ((s=backchar(f | FFRAND, n)) == TRUE)
  314.         s = ldelete((RSIZE) n, (f & FFARG) ? KFORW : KNONE);
  315.     return s;
  316. }
  317.  
  318. /*
  319.  * Kill line. If called without an argument,
  320.  * it kills from dot to the end of the line, unless it
  321.  * is at the end of the line, when it kills the newline.
  322.  * If called with an argument of 0, it kills from the
  323.  * start of the line to dot. If called with a positive